
int objhash(){
	return 0;
}

///*
// *  Checkpoint-restart - object hash infrastructure to manage shared objects
// *
// *  Copyright (C) 2008-2009 Oren Laadan
// *
// *  This file is subject to the terms and conditions of the GNU General Public
// *  License.  See the file COPYING in the main directory of the Linux
// *  distribution for more details.
// */
//
///* default debug level for output */
//#define CKPT_DFLAG  CKPT_DOBJ
//
//#include <linux/kernel.h>
//#include <linux/module.h>
//#include <linux/slab.h>
//#include <linux/hash.h>
//#include <linux/file.h>
//#include <linux/sched.h>
//#include <linux/checkpoint.h>
//
//struct ckpt_obj {
//	int users;
//	int objref;
//	int flags;
//	void *ptr;
//	const struct ckpt_obj_ops *ops;
//	struct hlist_node hash;
//	struct hlist_node next;
//};
//
///*` object internal flags */
//#define CKPT_OBJ_CHECKPOINTED		0x1   /* object already checkpointed */
//#define CKPT_OBJ_VISITED		0x2   /* object already visited */
//
//struct ckpt_obj_hash {
//	struct hlist_head *head;
//	struct hlist_head list;
//	int next_free_objref;
//};
//
///* ignored object */
//static const struct ckpt_obj_ops ckpt_obj_ignored_ops = {
//	.obj_name = "IGNORED",
//	.obj_type = CKPT_OBJ_IGNORE,
//	.ref_drop = NULL,
//	.ref_grab = NULL,
//};
//
///* objects array */
//static const struct ckpt_obj_ops *ckpt_obj_ops[CKPT_OBJ_MAX] = {
//	[CKPT_OBJ_IGNORE] = &ckpt_obj_ignored_ops,
//};
//
//int register_checkpoint_obj(const struct ckpt_obj_ops *ops)
//{
//	if (ops->obj_type < 0 || ops->obj_type >= CKPT_OBJ_MAX)
//		return -EINVAL;
//	if (ckpt_obj_ops[ops->obj_type] != NULL)
//		return -EINVAL;
//	ckpt_obj_ops[ops->obj_type] = ops;
//	return 0;
//}
//EXPORT_SYMBOL(register_checkpoint_obj);
//
//#define CKPT_OBJ_HASH_NBITS  10
//#define CKPT_OBJ_HASH_TOTAL  (1UL << CKPT_OBJ_HASH_NBITS)
//
//static void obj_hash_free(struct ckpt_obj_hash *obj_hash, int drop, int clean)
//{
//	struct hlist_head *h = obj_hash->head;
//	struct hlist_node *n, *t;
//	struct ckpt_obj *obj;
//	int i;
//
//	for (i = 0; i < CKPT_OBJ_HASH_TOTAL; i++) {
//		hlist_for_each_entry_safe(obj, n, t, &h[i], hash) {
//			if (drop && obj->ops->ref_drop)
//				obj->ops->ref_drop(obj->ptr, 1);
//			if (clean)
//				kfree(obj);
//		}
//	}
//}
//
//void ckpt_obj_hash_drop(struct ckpt_ctx *ctx)
//{
//	obj_hash_free(ctx->obj_hash, 1, 0);
//	ckpt_set_ctx_kflag(ctx, CKPT_CTX_DROPPED);
//}
//
//void ckpt_obj_hash_free(struct ckpt_ctx *ctx)
//{
//	struct ckpt_obj_hash *obj_hash = ctx->obj_hash;
//	int dropped = ctx->kflags & CKPT_CTX_DROPPED;
//
//	if (obj_hash) {
//		obj_hash_free(obj_hash, !dropped, 1);
//		kfree(obj_hash->head);
//		kfree(ctx->obj_hash);
//		ctx->obj_hash = NULL;
//	}
//}
//
//int ckpt_obj_hash_alloc(struct ckpt_ctx *ctx)
//{
//	struct ckpt_obj_hash *obj_hash;
//	struct hlist_head *head;
//
//	obj_hash = kzalloc(sizeof(*obj_hash), GFP_KERNEL);
//	if (!obj_hash)
//		return -ENOMEM;
//	head = kzalloc(CKPT_OBJ_HASH_TOTAL * sizeof(*head), GFP_KERNEL);
//	if (!head) {
//		kfree(obj_hash);
//		return -ENOMEM;
//	}
//
//	obj_hash->head = head;
//	obj_hash->next_free_objref = 1;
//	INIT_HLIST_HEAD(&obj_hash->list);
//
//	ctx->obj_hash = obj_hash;
//	return 0;
//}
//
//static struct ckpt_obj *obj_find_by_ptr(struct ckpt_ctx *ctx, void *ptr)
//{
//	struct hlist_head *h;
//	struct hlist_node *n;
//	struct ckpt_obj *obj;
//
//	h = &ctx->obj_hash->head[hash_long((unsigned long) ptr,
//					   CKPT_OBJ_HASH_NBITS)];
//	hlist_for_each_entry(obj, n, h, hash)
//		if (obj->ptr == ptr)
//			return obj;
//	return NULL;
//}
//
//static struct ckpt_obj *obj_find_by_objref(struct ckpt_ctx *ctx, int objref)
//{
//	struct hlist_head *h;
//	struct hlist_node *n;
//	struct ckpt_obj *obj;
//
//	h = &ctx->obj_hash->head[hash_long((unsigned long) objref,
//					   CKPT_OBJ_HASH_NBITS)];
//	hlist_for_each_entry(obj, n, h, hash)
//		if (obj->objref == objref)
//			return obj;
//	return NULL;
//}
//
//static inline int obj_alloc_objref(struct ckpt_ctx *ctx)
//{
//	return ctx->obj_hash->next_free_objref++;
//}
//
///**
// * ckpt_obj_new - add an object to the obj_hash
// * @ctx: checkpoint context
// * @ptr: pointer to object
// * @objref: object unique id
// * @ops: object operations
// *
// * Add the object to the obj_hash. If @objref is zero, assign a unique
// * object id and use @ptr as a hash key [checkpoint]. Else use @objref
// * as a key [restart].
// */
//static struct ckpt_obj *obj_new(struct ckpt_ctx *ctx, void *ptr,
//				int objref, enum obj_type type)
//{
//	const struct ckpt_obj_ops *ops = ckpt_obj_ops[type];
//	struct ckpt_obj *obj;
//	int i, ret;
//
//	/* explicitly disallow null pointers */
//	if (!ptr) {
//		ckpt_err(ctx, -EINVAL, "checkpointing NULL type %d\n", type);
//		return ERR_PTR(-EINVAL);
//	}
//
//	/* make sure we don't change this accidentally */
//	if (ops->obj_type != type) {
//		ckpt_err(ctx, -EINVAL, "type mismatch: %d->ops->obj_type %d\n",
//			type, ops->obj_type);
//		return ERR_PTR(-EINVAL);
//	}
//
//	obj = kzalloc(sizeof(*obj), GFP_KERNEL);
//	if (!obj)
//		return ERR_PTR(-ENOMEM);
//
//	obj->ptr = ptr;
//	obj->ops = ops;
//	obj->users = 2;  /* extra reference that objhash itself takes */
//
//	if (!objref) {
//		/* use @obj->ptr to index, assign objref (checkpoint) */
//		obj->objref = obj_alloc_objref(ctx);
//		i = hash_long((unsigned long) ptr, CKPT_OBJ_HASH_NBITS);
//	} else {
//		/* use @obj->objref to index (restart) */
//		obj->objref = objref;
//		i = hash_long((unsigned long) objref, CKPT_OBJ_HASH_NBITS);
//	}
//
//	ret = ops->ref_grab ? ops->ref_grab(obj->ptr) : 0;
//	if (ret < 0) {
//		kfree(obj);
//		obj = ERR_PTR(ret);
//	} else {
//		hlist_add_head(&obj->hash, &ctx->obj_hash->head[i]);
//		hlist_add_head(&obj->next, &ctx->obj_hash->list);
//	}
//
//	return obj;
//}
//
///**
// * ckpt_obj_del - delete an object from the obj_hash
// * @ctx: checkpoint context
// * @obj: object pointer
// *
// * Delete the object @obj from the obj_hash.  This is not something
// * that I would expect to be used in normal situations, but it makes
// * the error path of codependent network interfaces much smoother.
// */
//static void ckpt_obj_del(struct ckpt_ctx *ctx, struct ckpt_obj *obj)
//{
//	hlist_del(&obj->hash);
//	hlist_del(&obj->next);
//	if (obj->ops->ref_drop)
//		obj->ops->ref_drop(obj->ptr, 1);
//	kfree(obj);
//}
//
///**************************************************************************
// * Checkpoint
// */
//
///**
// * obj_lookup_add - lookup object and add if not in objhash
// * @ctx: checkpoint context
// * @ptr: pointer to object
// * @type: object type
// * @first: [output] first encounter (added to table)
// *
// * Look up the object pointed to by @ptr in the hash table. If it isn't
// * already found there, add the object, and allocate a unique object
// * id. Grab a reference to every object that is added, and maintain the
// * reference until the entire hash is freed.
// */
//static struct ckpt_obj *obj_lookup_add(struct ckpt_ctx *ctx, void *ptr,
//				       enum obj_type type, int *first)
//{
//	struct ckpt_obj *obj;
//
//	obj = obj_find_by_ptr(ctx, ptr);
//	if (!obj) {
//		obj = obj_new(ctx, ptr, 0, type);
//		*first = 1;
//	} else {
//		BUG_ON(obj->ops->obj_type != type);
//		obj->users++;
//		*first = 0;
//	}
//	return obj;
//}
//
///**
// * ckpt_obj_collect - collect object into objhash
// * @ctx: checkpoint context
// * @ptr: pointer to object
// * @type: object type
// *
// * [used during checkpoint].
// * Return: objref if object is new, 0 otherwise, or an error
// */
//int ckpt_obj_collect(struct ckpt_ctx *ctx, void *ptr, enum obj_type type)
//{
//	struct ckpt_obj *obj;
//	int first;
//
//	obj = obj_lookup_add(ctx, ptr, type, &first);
//	if (IS_ERR(obj))
//		return PTR_ERR(obj);
//	ckpt_debug("%s objref %d first %d\n",
//		   obj->ops->obj_name, obj->objref, first);
//	return first ? obj->objref : 0;
//}
//
///**
// * ckpt_obj_lookup - lookup object (by pointer) in objhash
// * @ctx: checkpoint context
// * @ptr: pointer to object
// * @type: object type
// *
// * [used during checkpoint].
// * Return: objref (or zero if not found)
// */
//int ckpt_obj_lookup(struct ckpt_ctx *ctx, void *ptr, enum obj_type type)
//{
//	struct ckpt_obj *obj;
//
//	obj = obj_find_by_ptr(ctx, ptr);
//	BUG_ON(obj && obj->ops->obj_type != type);
//	if (obj)
//		ckpt_debug("%s objref %d\n", obj->ops->obj_name, obj->objref);
//	return obj ? obj->objref : 0;
//}
//EXPORT_SYMBOL(ckpt_obj_lookup);
//
//static inline int obj_reverse_leak(struct ckpt_ctx *ctx, struct ckpt_obj *obj)
//{
//	/*
//	 * A "reverse" leak ?  All objects should already be in the
//	 * objhash by now. But an outside task may have created an
//	 * object while we were collecting, which we didn't catch.
//	 */
//	if (obj->ops->ref_users && !(ctx->uflags & CHECKPOINT_SUBTREE)) {
//		ckpt_err(ctx, -EBUSY, "%(O)%(P)Leak: reverse added late (%s)\n",
//			       obj->objref, obj->ptr, obj->ops->obj_name);
//		return -EBUSY;
//	}
//	return 0;
//}
//
///**
// * ckpt_obj_lookup_add - lookup object and add if not in objhash
// * @ctx: checkpoint context
// * @ptr: pointer to object
// * @type: object type
// * @first: [output] first encoutner (added to table)
// *
// * [used during checkpoint].
// * Return: objref
// */
//int ckpt_obj_lookup_add(struct ckpt_ctx *ctx, void *ptr,
//			enum obj_type type, int *first)
//{
//	struct ckpt_obj *obj;
//
//	obj = obj_lookup_add(ctx, ptr, type, first);
//	if (IS_ERR(obj))
//		return PTR_ERR(obj);
//	ckpt_debug("%s objref %d first %d\n",
//		   obj->ops->obj_name, obj->objref, *first);
//
//	if (*first && obj_reverse_leak(ctx, obj))
//		return -EBUSY;
//
//	obj->flags |= CKPT_OBJ_VISITED;
//	return obj->objref;
//}
//EXPORT_SYMBOL(ckpt_obj_lookup_add);
//
///**
// * ckpt_obj_reserve - reserve an objref
// * @ctx: checkpoint context
// *
// * The reserved objref will not be used for subsequent objects. This
// * gives an objref that can be safely used during restart without a
// * matching object in checkpoint.  [used during checkpoint].
// */
//int ckpt_obj_reserve(struct ckpt_ctx *ctx)
//{
//	return obj_alloc_objref(ctx);
//}
//EXPORT_SYMBOL(ckpt_obj_reserve);
//
///**
// * checkpoint_obj - if not already in hash, add object and checkpoint
// * @ctx: checkpoint context
// * @ptr: pointer to object
// * @type: object type
// *
// * Use obj_lookup_add() to lookup (and possibly add) the object to the
// * hash table. If the CKPT_OBJ_CHECKPOINTED flag isn't set, then also
// * save the object's state using its ops->checkpoint().
// *
// * [This is used during checkpoint].
// * Returns: objref
// */
//int checkpoint_obj(struct ckpt_ctx *ctx, void *ptr, enum obj_type type)
//{
//	struct ckpt_hdr_objref *h;
//	struct ckpt_obj *obj;
//	int new, ret = 0;
//
//	obj = obj_lookup_add(ctx, ptr, type, &new);
//	if (IS_ERR(obj))
//		return PTR_ERR(obj);
//
//	if (new && obj_reverse_leak(ctx, obj))
//		return -EBUSY;
//
//	if (!(obj->flags & CKPT_OBJ_CHECKPOINTED)) {
//		h = ckpt_hdr_get_type(ctx, sizeof(*h), CKPT_HDR_OBJREF);
//		if (!h)
//			return -ENOMEM;
//
//		h->objtype = type;
//		h->objref = obj->objref;
//		ret = ckpt_write_obj(ctx, &h->h);
//		ckpt_hdr_put(ctx, h);
//
//		if (ret < 0)
//			return ret;
//
//		/* invoke callback to actually dump the state */
//		BUG_ON(!obj->ops->checkpoint);
//
//		obj->flags |= CKPT_OBJ_CHECKPOINTED;
//		ret = obj->ops->checkpoint(ctx, ptr);
//	}
//
//	obj->flags |= CKPT_OBJ_VISITED;
//	return (ret < 0 ? ret : obj->objref);
//}
//EXPORT_SYMBOL(checkpoint_obj);
//
///**
// * ckpt_obj_visit - mark object as visited
// * @ctx: checkpoint context
// * @ptr: pointer to object
// * @type: object type
// *
// * [used during checkpoint].
// * Marks the object as visited, or fail if not found
// */
//int ckpt_obj_visit(struct ckpt_ctx *ctx, void *ptr, enum obj_type type)
//{
//	struct ckpt_obj *obj;
//
//	obj = obj_find_by_ptr(ctx, ptr);
//	BUG_ON(obj && obj->ops->obj_type != type);
//
//	if (!obj) {
//		if (!(ctx->uflags & CHECKPOINT_SUBTREE)) {
//			/* if not found report reverse leak (full container) */
//			ckpt_err(ctx, -EBUSY,
//				 "%(O)%(P)Leak: reverse unknown (%s)\n",
//				 obj->objref, obj->ptr, obj->ops->obj_name);
//			return -EBUSY;
//		}
//	} else {
//		ckpt_debug("visit %s objref %d\n",
//			   obj->ops->obj_name, obj->objref);
//		obj->flags |= CKPT_OBJ_VISITED;
//	}
//	return 0;
//}
//EXPORT_SYMBOL(ckpt_obj_visit);
//
///* increment the 'users' count of an object */
//static void ckpt_obj_users_inc(struct ckpt_ctx *ctx, void *ptr, int increment)
//{
//	struct ckpt_obj *obj;
//
//	obj = obj_find_by_ptr(ctx, ptr);
//	if (obj)
//		obj->users += increment;
//}
//
///*
// * "Leak detection" - to guarantee a consistent checkpoint of a full
// * container we verify that all resources are confined and isolated in
// * that container:
// *
// * c/r code first walks through all tasks and collects all shared
// * resources into the objhash, while counting the references to them;
// * then, it compares this count to the object's real reference count,
// * and if they don't match it means that an object has "leaked" to the
// * outside.
// *
// * Otherwise, it is guaranteed that there are no references outside
// * (of container). c/r code now proceeds to walk through all tasks,
// * again, and checkpoints the resources. It ensures that all resources
// * are already in the objhash, and that all of them are checkpointed.
// * Otherwise it means that due to a race, an object was created or
// * destroyed during the first walk but not accounted for.
// *
// * For instance, consider an outside task A that shared files_struct
// * with inside task B. Then, after B's files where collected, A opens
// * or closes a file, and immediately exits - before the first leak
// * test is performed, such that the test passes.
// */
//
///**
// * obj_sock_adjust_users - remove implicit reference on DEAD sockets
// * @obj: CKPT_OBJ_SOCK object to adjust
// *
// * Sockets that have been disconnected from their struct file may have
// * a reference count one less than normal sockets.  The objhash's
// * assumption of such a reference is therefore incorrect, so we correct
// * it here.
// */
//static inline void obj_sock_adjust_users(struct ckpt_obj *obj)
//{
//	struct sock *sk = (struct sock *)obj->ptr;
//
//	if (sock_flag(sk, SOCK_DEAD)) {
//		obj->users = obj->ops->ref_users(obj->ptr);
//		ckpt_debug("Adjusting SOCK %i count to %i\n",
//			   obj->objref, obj->users);
//	}
//}

/**
 * ckpt_obj_contained - test if shared objects are contained in checkpoint
 * @ctx: checkpoint context
 *
 * Loops through all objects in the table and compares the number of
 * references accumulated during checkpoint, with the reference count
 * reported by the kernel.
 *
 * Return 1 if respective counts match for all objects, 0 otherwise.
 */
//int ckpt_obj_contained(struct ckpt_ctx *ctx)
//{
//	struct ckpt_obj *obj;
//	struct hlist_node *node;
//
//	/* account for ctx->{file,logfile} (if in the table already) */
//	ckpt_obj_users_inc(ctx, ctx->file, 1);
//	if (ctx->logfile)
//		ckpt_obj_users_inc(ctx, ctx->logfile, 1);
//	/* account for ctx->root_nsproxy (if in the table already) */
//	ckpt_obj_users_inc(ctx, ctx->root_nsproxy, 1);
//
//	hlist_for_each_entry(obj, node, &ctx->obj_hash->list, next) {
//		if (!obj->ops->ref_users)
//			continue;
//
//		if (obj->ops->obj_type == CKPT_OBJ_SOCK)
//			obj_sock_adjust_users(obj);
//
//		if (obj->ops->ref_users(obj->ptr) != obj->users) {
//			ckpt_err(ctx, -EBUSY,
//				 "%(O)%(P)%(S)Usage leak (%d != %d)\n",
//				 obj->objref, obj->ptr, obj->ops->obj_name,
//				 obj->ops->ref_users(obj->ptr), obj->users);
//			return 0;
//		}
//	}
//
//	return 1;
//}

///**
// * ckpt_obj_visited - test that all shared objects were visited
// * @ctx: checkpoint context
// *
// * Return 1 if all objects where visited, 0 otherwise.
// */
//int ckpt_obj_visited(struct ckpt_ctx *ctx)
//{
//	struct ckpt_obj *obj;
//	struct hlist_node *node;
//
//	hlist_for_each_entry(obj, node, &ctx->obj_hash->list, next) {
//		if (!(obj->flags & CKPT_OBJ_VISITED)) {
//			ckpt_err(ctx, -EBUSY,
//				 "%(O)%(P)%(S)Leak: not visited\n",
//				 obj->objref, obj->ptr, obj->ops->obj_name);
//			return 0;
//		}
//	}
//
//	return 1;
//}
//
///**************************************************************************
// * Restart
// */
//
///**
// * restore_obj - read in and restore a (first seen) shared object
// * @ctx: checkpoint context
// * @h: ckpt_hdr of shared object
// *
// * Read in the header payload (struct ckpt_hdr_objref). Lookup the
// * object to verify it isn't there.  Then restore the object's state
// * and add it to the objash. No need to explicitly grab a reference -
// * we hold the initial instance of this object. (Object maintained
// * until the entire hash is free).
// *
// * [This is used during restart].
// */
//int restore_obj(struct ckpt_ctx *ctx, struct ckpt_hdr_objref *h)
//{
//	const struct ckpt_obj_ops *ops;
//	struct ckpt_obj *obj;
//	void *ptr = ERR_PTR(-EINVAL);
//
//	ckpt_debug("len %d ref %d type %d\n", h->h.len, h->objref, h->objtype);
//	if (h->objtype >= CKPT_OBJ_MAX)
//		return -EINVAL;
//	if (h->objref <= 0)
//		return -EINVAL;
//
//	ops = ckpt_obj_ops[h->objtype];
//	if (!ops)
//		return -ENOSYS;
//
//	BUG_ON(ops->obj_type != h->objtype);
//
//	if (ops->restore)
//		ptr = ops->restore(ctx);
//	if (IS_ERR(ptr))
//		return PTR_ERR(ptr);
//
//	obj = obj_find_by_objref(ctx, h->objref);
//	if (!obj) {
//		obj = obj_new(ctx, ptr, h->objref, h->objtype);
//		/*
//		 * Drop an extra reference to the object returned by
//		 * ops->restore to balance the one taken by obj_new()
//		 */
//		if (!IS_ERR(obj) && ops->ref_drop)
//			ops->ref_drop(ptr, 0);
//	} else if ((obj->ptr != ptr) || (obj->ops->obj_type != h->objtype)) {
//		/* Normally, we expect an object to not already exist
//		 * in the hash.  However, for some special scenarios
//		 * where we're restoring sets of objects that must be
//		 * co-allocated (such, as veth netdev pairs) we need
//		 * to tolerate this case if the second restore returns
//		 * the correct type and pointer, as specified in the
//		 * existing object.  If either of those don't match,
//		 * we fail.
//		 */
//		obj = ERR_PTR(-EINVAL);
//	}
//
//	if (IS_ERR(obj)) {
//		/* This releases our final reference on the object
//		 * returned by ops->restore()
//		 */
//		if (ops->ref_drop)
//			ops->ref_drop(ptr, 1);
//		return PTR_ERR(obj);
//	}
//	return obj->objref;
//}
//
///**
// * ckpt_obj_insert - add an object with a given objref to obj_hash
// * @ctx: checkpoint context
// * @ptr: pointer to object
// * @objref: unique object id
// * @type: object type
// *
// * Add the object pointer to by @ptr and identified by unique object id
// * @objref to the hash table (indexed by @objref).  Grab a reference to
// * every object added, and maintain it until the entire hash is freed.
// *
// * [This is used during restart].
// */
//int ckpt_obj_insert(struct ckpt_ctx *ctx, void *ptr,
//		    int objref, enum obj_type type)
//{
//	struct ckpt_obj *obj;
//
//	if (objref <= 0)
//		return -EINVAL;
//	if (obj_find_by_objref(ctx, objref))
//		return -EINVAL;
//	obj = obj_new(ctx, ptr, objref, type);
//	if (IS_ERR(obj))
//		return PTR_ERR(obj);
//	ckpt_debug("%s objref %d\n", obj->ops->obj_name, objref);
//	return obj->objref;
//}
//EXPORT_SYMBOL(ckpt_obj_insert);
//
///**
// * ckpt_obj_del - delete object (by pointer) in objhash
// * @ctx: checkpoint context
// * @ref: object reference
// * @type: object type
// *
// * Return: nonzero on failure
// */
//int ckpt_obj_delete(struct ckpt_ctx *ctx, int objref, enum obj_type type)
//{
//	struct ckpt_obj *obj;
//
//	obj = obj_find_by_objref(ctx, objref);
//	BUG_ON(obj && obj->ops->obj_type != type);
//	if (obj) {
//		ckpt_debug("%s deleted from hash\n", obj->ops->obj_name);
//		ckpt_obj_del(ctx, obj);
//	}
//
//	return obj ? 0 : -ESRCH;
//}
//EXPORT_SYMBOL(ckpt_obj_delete);
//
///**
// * ckpt_obj_try_fetch - fetch an object by its identifier
// * @ctx: checkpoint context
// * @objref: object id
// * @type: object type
// *
// * Lookup the objref identifier by @objref in the hash table. Return
// * an error not found.
// *
// * [This is used during restart].
// */
//void *ckpt_obj_try_fetch(struct ckpt_ctx *ctx, int objref, enum obj_type type)
//{
//	struct ckpt_obj *obj;
//
//	obj = obj_find_by_objref(ctx, objref);
//	if (!obj)
//		return ERR_PTR(-EINVAL);
//	ckpt_debug("%s ref %d\n", obj->ops->obj_name, obj->objref);
//	if (obj->ops->obj_type == type)
//		return obj->ptr;
//	return ERR_PTR(-ENOMSG);
//}
//EXPORT_SYMBOL(ckpt_obj_try_fetch);
//
//void *ckpt_obj_fetch(struct ckpt_ctx *ctx, int objref, enum obj_type type)
//{
//	void *ret = ckpt_obj_try_fetch(ctx, objref, type);
//
//	if (unlikely(IS_ERR(ret)))
//		ckpt_err(ctx, PTR_ERR(ret), "%(O)Fetching object (type %d)\n",
//			 objref, type);
//	return ret;
//}
//EXPORT_SYMBOL(ckpt_obj_fetch);sss
